import 'dart:async';

import 'package:event_listener/bean/EventNotifyBean.dart';
import 'package:event_listener/enums/EventNotify.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

import 'event_listener_platform_interface.dart';

/// An implementation of [EventListenerPlatform] that uses method channels.
class MethodChannelEventListener extends EventListenerPlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('event_listener');

  bool _init = false;

  Stream<EventNotifyBean>? _onEventNotifyChanged;
  final StreamController<MethodCall> _streamController = StreamController();

  @override
  Future<String?> getPlatformVersion() async {
    final version = await _invokeMethod<String>('getPlatformVersion');
    return version;
  }

  @override
  Future<void> startListening() async{
    await _invokeMethod("startListening");
  }

  Future<T?> _invokeMethod<T>(String method, [ dynamic args ]) async{
    if(!_init){
      _init = true;
      _initPlugin();
    }
    return await methodChannel.invokeMethod<T>(method, args);
  }

  void _initPlugin(){
    methodChannel.setMethodCallHandler(_methodCallHandler);
  }

  Future<dynamic> _methodCallHandler(MethodCall call) async {
    _streamController.add(call);
  }

  /// Fires whenever the battery state changes.
  @override
  Stream<EventNotifyBean> get onEventNotifyChanged {
    _onEventNotifyChanged ??= _streamController.stream
        .map((MethodCall event) => parseEventNotify(event));
    return _onEventNotifyChanged!;
  }
}
